package model

import (
	"fmt"
	"gowork/hotelOrder/utils"
	"strconv"
	"sync"
	"time"
)

type Room struct {
	Id int64 `xorm:"pk autoincr"`
	Type int64
	Name string
	Window bool
	Breakfast string
	BedType string
	Floor string
	TheMeasureOfArea string
	Number int
	SumCount int
	Reserved bool `xorm:"-"`
	CreatedAt time.Time
	UpdatedAt time.Time
}

type HotelOrder struct {
	Id int64 `xorm:"pk autoincr"`
	DateOfStayList []string `xorm:"-"`
	RoomList []*Room `xorm:"-"`
	ReservedBy string
	Phone int64
	EstimatedTimeOfArrival string
	SpecialRequirements string
	CreatedAt time.Time
	UpdatedAt time.Time
}

type CheckInInformation struct {
	Id int64 `xorm:"pk autoincr"`
	RoomId int64
	RoomTypeId int64
	RoomNumber int
	HotelOrderId int64
	ResidentName string
	CheckInTime string
	State int    // 1 未入住  2 已入住   3已离店
	CreatedAt time.Time
	UpdatedAt time.Time
}

type RoomManagement struct {
	Id int64 `xorm:"pk autoincr"`
	Type int64
	Name string
	Number int
	CreatedAt time.Time
	UpdatedAt time.Time
}

var lock sync.Mutex

func (ho *HotelOrder)PlaceAnOrder(hov *HotelOrder, residentName string) (map[string]interface{}, error){

	w := new(utils.Worker)

	hov.Id = w.GetId()
	hov.CreatedAt = time.Now()
	hov.UpdatedAt = time.Now()

	for _, rv := range hov.RoomList{
		for i:=0; i < rv.Number; i++ {
			for _, dosv := range hov.DateOfStayList{

				lock.Lock()

				var rm RoomManagement
				x.Where("type = ?", rv.Type).Get(&rm)
				total, err := x.Where("check_in_time = ?", dosv).And("room_type_id = ?", rv.Type).Count(new(CheckInInformation))
				if err != nil{

					lock.Unlock()

					return nil, err
				}
				if int(total)+1 > rm.Number{

					lock.Unlock()

					return map[string]interface{}{"message":dosv + "日" +rv.Name + "该类型的房间已满", "data":nil, "code":400}, nil
				}

				var cii CheckInInformation
				cii.Id = w.GetId()
				cii.RoomTypeId = rv.Type
				cii.RoomNumber = rv.Number
				cii.CheckInTime = dosv
				cii.State = 1
				cii.HotelOrderId = hov.Id
				cii.ResidentName = residentName
				cii.CreatedAt = time.Now()
				cii.UpdatedAt = time.Now()
				x.Insert(&cii)

				lock.Unlock()

			}
		}
	}

	x.Insert(hov)

	return map[string]interface{}{"message":"成功", "data":nil, "code":200}, nil
}

func (ho *HotelOrder)HotelReservation(dList []string, rt int64, roomHouseholdList []string)(map[string]interface{}, error){

	w := new(utils.Worker)

	for _, d := range dList {
		for _, rh := range roomHouseholdList {
			var cii = CheckInInformation{
				Id:        w.GetId(),
				RoomTypeId:  rt,
				ResidentName: rh,
				CheckInTime: d,
				State:       1,
				CreatedAt:   time.Now(),
				UpdatedAt:   time.Now(),
			}
			x.Insert(&cii)
		}
	}

	return map[string]interface{}{"message":"成功", "data":nil, "code":200}, nil
}

func (ho *HotelOrder)CheckIn(ciiId int64, rId int64)(map[string]interface{}, error){

	var cii CheckInInformation
	cii.RoomId = rId
	cii.State = 2
	x.Id(ciiId).Update(&cii)


	return map[string]interface{}{"message":"成功", "data":nil, "code":200}, nil
}

type ResRoom struct {
	Id string
	Type string
	Name string
	Window string
	Breakfast string
	BedType string
	Floor string
	TheMeasureOfArea string
	Number int
	SumCount int
	Reserved string
	CreatedAt string
	UpdatedAt string
}

func (ho *HotelOrder)QueryRoomInfo(pageNo int,  pageSize int)([]*ResRoom, int, error){

	fmt.Println("page：", pageNo)
	var rrList []*ResRoom
	var rList []*Room
	total, _ := x.Count(new(Room))
	x.Limit(pageSize, (pageNo-1)*pageSize).Find(&rList)
	for _, r := range rList{
		var cii CheckInInformation
		x.Where("room_id = ?", r.Id).And("check_in_time = ?", time.Now().Format("2006-01-02")).Get(&cii)
		if cii.Id != 0{
			r.Reserved = true
		}

		var rr = ResRoom{
			Id: strconv.FormatInt(r.Id,10),
			Type: strconv.FormatInt(r.Type,10),
			Name:             r.Name,
			Window:           strconv.FormatBool(r.Window),
			Breakfast:        r.Breakfast,
			BedType:          r.BedType,
			Floor:            r.Floor,
			TheMeasureOfArea: r.TheMeasureOfArea,
			Number:           r.Number,
			SumCount:         r.SumCount,
			Reserved:         strconv.FormatBool(r.Reserved),
			CreatedAt:        r.CreatedAt.Format("2006-01-02 15:04:05"),
			UpdatedAt:        r.UpdatedAt.Format("2006-01-02 15:04:05"),
		}
		rrList = append(rrList, &rr)
	}

	t ,_ := strconv.Atoi(strconv.FormatInt(total,10))
	return rrList, t, nil
}

























